/*  ----------------------------------------------------------------------------
 *  Arello Mobile
 *  Fast 3d Engine
 *  ----------------------------------------------------------------------------
 * Except where otherwise noted, this work is licensed under
 * http://creativecommons.org/licenses/by/3.0
 */

#ifndef __PICTUREFORMAT_DECOMPRESSORGIF_H__
#define __PICTUREFORMAT_DECOMPRESSORGIF_H__

#include "Decompressor.h"
#include <NoCopy.h>
#include <Gluck.h>

namespace liba
{
namespace pictureformat
{

typedef unsigned short int uint16_t;
typedef unsigned char uint8_t;

class DecompressorGif : public Decompressor, private Nocopy
{
	typedef unsigned int OutputFormat;

	uint16_t pallete_size;
	void load_pallete(ColorPacked *pallete);

	bool find_image_descriptor();

	const uint8_t *current_ptr, *last_ptr;
	uint16_t bits_remainder;

	uint16_t read_next_code(uint16_t bits);
	void move_next_byte();

	pictureformat::Format desired_format;
	int m_width;
	int m_height;
	bool valid;

	int scan_line;

	ColorPacked * pallete;

	ColorPacked * decoded_data;

	uint16_t code_size;
	uint16_t clear_code;

	uint16_t eof_code;
	uint16_t bit_mask;

	uint16_t initial_code_size;
	uint16_t initial_max_code;
	uint16_t initial_free_code;

	uint16_t max_code;
	uint16_t free_code;

	uint16_t * out_codes;
	int out_codes_count;

	uint16_t * prefix;
	uint16_t * suffix;

	uint16_t input_code, previous_code, result;
	uint16_t code;

	const void * data;
public:
	DecompressorGif(const void * data, int size);
	virtual ~DecompressorGif();
	virtual int get_width(int frame)const
	{
		return m_width;
	}
	virtual int get_height(int frame)const
	{
		return m_height;
	}
	virtual Format get_best_format()const
	{
		return pictureformat::R8G8B8;
	}
	virtual int get_frame_count()const
	{
		return 1;
	}
	virtual void reset(Format f, int frame)
	{
		if( frame > 0 )
			THROW(Gluck( __FUNCTION__, "Frame is out of range" ));
		desired_format = f;
		scan_line = 0;
	}
	virtual void unpack_scanline(void * dst);
	virtual void skip_scanline(int count);
};

} // namespace pictureformat
} // namespace liba
using namespace liba;

#endif //__PICTUREFORMAT_DECOMPRESSORGIF_H__